package com.bamboo.core.util;

import com.bamboo.core.exceptions.BambooException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
* @description 与注解相关的工具方法
* @date 2025/3/6 11:40
* @author chenzh
*/
public class AnnotationUtil {
    /**
     * @description 获取类级别的注解实例
     * @date 2025/3/6 14:30
     * @author chenzh
     * @param joinPoint 切面方法依赖注入的参数
     * @param annotationClass 期望得到的注解类型
     * @param <A> 指定annotationClass的类型范围
     * @return Annotation
     */
    public static <A extends Annotation>Annotation getClassLevelAnnotation(JoinPoint joinPoint, Class<A> annotationClass) {
        Class<?> targetCls = joinPoint.getTarget().getClass();
        if (targetCls.isAnnotationPresent(annotationClass)) {
            return targetCls.getAnnotation(annotationClass);
        }
        throw new BambooException(String.format("类(%s)不存在指定的注解(%s)", targetCls.getName(), annotationClass.getName()));
    }

    /**
     * @description 获取方法级别上的注解实例
     * @date 2025/3/6 14:33
     * @author chenzh
     * @param joinPoint @see com.bamboo.common.util.AnnotationUtil#getClassLevelAnnotation(org.aspectj.lang.JoinPoint, java.lang.Class)
     * @param annotationClass @see com.bamboo.common.util.AnnotationUtil#getClassLevelAnnotation(org.aspectj.lang.JoinPoint, java.lang.Class)
     * @param <A> @see com.bamboo.common.util.AnnotationUtil#getClassLevelAnnotation(org.aspectj.lang.JoinPoint, java.lang.Class)
     * @return Annotation
     */
    public static <A extends Annotation>Annotation getMethodLevelAnnotation(JoinPoint joinPoint, Class<A> annotationClass) {
        MethodSignature methodSign = (MethodSignature) joinPoint.getSignature();
        Method method = methodSign.getMethod();
        A annotation = method.getAnnotation(annotationClass);
        if (annotation == null) {
            throw new BambooException(String.format(
                    "类(%s)不存在指定的注解(%s)",
                    joinPoint.getTarget().getClass().getName(),
                    annotationClass.getName()
            ));
        }
        return annotation;
    }
}
